package com.ruoyi.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.app.domain.*;
import com.ruoyi.app.domain.vo.OrderInfoVo;
import com.ruoyi.app.domain.vo.OrderProductVo;
import com.ruoyi.app.domain.vo.RestockProductVo;
import com.ruoyi.app.enums.OrderInfoGroupTypeEnum;
import com.ruoyi.app.enums.ProductInfoTypeEnum;
import com.ruoyi.app.mapper.OrderInfoMapper;
import com.ruoyi.app.service.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.OrderNumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.MathContext;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 订单详情Service业务层处理
 * 
 * @author zhangkaiqiang
 * @date 2024-10-20
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements IOrderInfoService
{
    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private IProductInfoService productInfoService;

    @Autowired
    private IOrderProductService orderProductService;

    @Autowired
    private IShopCustomerService shopCustomerService;


    @Autowired
    private IShopInfoService shopInfoService;

    /**
     * 查询订单详情
     * 
     * @param id 订单详情主键
     * @return 订单详情
     */
    @Override
    public OrderInfoVo selectOrderInfoById(String id)
    {
        OrderInfo orderInfo = baseMapper.selectById(id);
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        if(orderInfo == null || StringUtils.isBlank(orderInfo.getId())){
            return orderInfoVo;
        }
        BeanUtils.copyProperties(orderInfo, orderInfoVo);
        orderInfoVo.setOrderProducts(orderProductService.listByOrderIds(Arrays.asList(orderInfoVo.getId())));
        return orderInfoVo;
    }

    /**
     * 查询订单详情列表
     * 
     * @param orderInfoVo 订单详情
     * @return 订单详情
     */
    @Override
    public List<OrderInfoVo> selectOrderInfoList(OrderInfoVo orderInfoVo)
    {
        LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>(orderInfoVo);
        lambdaQueryWrapper.eq(OrderInfo::getShopId, orderInfoVo.getShopId());
        lambdaQueryWrapper.orderByDesc(OrderInfo::getCreateTime);
        List<OrderInfo> orderInfos = baseMapper.selectList(lambdaQueryWrapper);
        if(CollectionUtils.isEmpty(orderInfos)){
            return new ArrayList<>();
        }
        HashSet<String> set = new HashSet<>();
        List<OrderInfoVo> orderInfoVos = orderInfos.stream().map(item -> {
            OrderInfoVo orderInfoVo1 = new OrderInfoVo();
            BeanUtils.copyProperties(item, orderInfoVo1);
            set.add(item.getId());
            return orderInfoVo1;
        }).collect(Collectors.toList());
        List<OrderProductVo> orderProducts = orderProductService.listByOrderIds(set);
        if(CollectionUtils.isEmpty(orderProducts)){
            return orderInfoVos;
        }
        Map<String, List<OrderProductVo>> collect = orderProducts.stream().collect(Collectors.groupingBy(OrderProduct::getOrderId));
        orderInfoVos.forEach(item ->{
            item.setOrderProducts(collect.get(item.getId()));
        });
        return orderInfoVos;
    }

    @Override
//    @Transient
    public String add(OrderInfoVo orderInfoVo) {
        if (orderInfoVo == null) {
            throw new ServiceException("订单信息不嫩为空");
        }
        List<OrderProductVo> orderProducts = orderInfoVo.getOrderProducts();
        if (CollectionUtils.isEmpty(orderProducts)) {
            throw new ServiceException("订单商品不能为空");
        }

        Set<String> productNames = orderProducts.stream().filter(item -> StringUtils.isBlank(item.getProductId())).map(OrderProduct::getProductName).collect(Collectors.toSet());
        if(!CollectionUtils.isEmpty(productNames)){
            Boolean result = productInfoService.verification(orderInfoVo.getShopId(), productNames);
            if(!result){
                throw new ServiceException("商品已存在");
            }
        }
//        Set<String> collect = orderProducts.stream().map(OrderProduct::getProductId).collect(Collectors.toSet());
//        List<ProductInfo> productInfos = productInfoService.listByIds(collect);
//        if (CollectionUtils.isEmpty(productInfos)) {
//            throw new ServiceException("存在已下架或不存在商品信息");
//        }
//        Map<String, ProductInfo> productInfoMap = productInfos.stream()
//                .collect(Collectors.toMap(ProductInfo::getId, Function.identity(), (i1, i2) -> i1));
        List<ProductInfo> inventoryProductInfos = new ArrayList<>();
        orderInfoVo.setOrderNo(OrderNumberUtils.generateOrderNumber(6));
        baseMapper.insert(orderInfoVo);
        // 逐个计算商品对数量和价格
        BigDecimal orderPurchasingPrice = new BigDecimal(0);
        BigDecimal orderSellingPrice = new BigDecimal(0);
        Long totalNumber = 0L;
        long i = 1L;
        List<OrderProduct> orderProducts1 = new ArrayList<>();
        for (OrderProductVo item : orderProducts){
            ProductInfo productInfo = null;
            if(StringUtils.isBlank(item.getProductId())){
                productInfo = new ProductInfo();
                BeanUtils.copyProperties(item, productInfo);
                productInfo.setShopId(orderInfoVo.getShopId());
                productInfo.setImg(item.getProductImg());
                productInfo.setCode(item.getProductCode());
                productInfo.setName(item.getProductName());
                productInfo.setCategoryId(item.getCategoryId());
                productInfo.setCategoryTxt(item.getCategoryTxt());
                productInfo.setTotalNumber(item.getTotalNumber());
                productInfo.setCurrentNumber(item.getTotalNumber());
                productInfo.setPurchasingPrice(item.getPurchasingPrice());
                productInfo.setSellingPrice(item.getSellingPrice());
                productInfo.setType(ProductInfoTypeEnum.ORDER.getType());
                productInfoService.addOrUpdate(productInfo);
            } else {
                productInfo = productInfoService.getById(item.getProductId());
            }
            if(item.getSellingPrice() != null){
                productInfo.setSellingPrice(item.getSellingPrice());
            }
//            ProductInfo productInfo = productInfoMap.get(item.getProductId());
            if (productInfo == null) {
                throw new ServiceException("存在已下架或不存在商品信息");
            }
            Long inventory = productInfo.getCurrentNumber() - item.getTotalNumber();
            if (inventory < 0){
                throw new ServiceException("当前商品一超出库存数量，请核对商品数量");
            }
            ProductInfo productInfo1 = new ProductInfo();
            productInfo1.setId(productInfo.getId());
            productInfo1.setCurrentNumber(inventory);
            inventoryProductInfos.add(productInfo1);
            item.setPurchasingPrice(productInfo.getPurchasingPrice());
//            item.setSellingPrice(productInfo.getSellingPrice());
            item.setShopId(orderInfoVo.getShopId());
            item.setOrderNo(orderInfoVo.getOrderNo());
            item.setOrderId(orderInfoVo.getId());
            item.setProductName(productInfo.getName());
            item.setProductImg(productInfo.getImg());
            item.setCategoryId(productInfo.getCategoryId());
            item.setCategoryTxt(productInfo.getCategoryTxt());
            BigDecimal purchasingPrice = productInfo.getPurchasingPrice();
//            BigDecimal purchasingPrice = item.getPurchasingPrice();
            totalNumber += item.getTotalNumber();
            if(purchasingPrice != null){
                item.setTotalPurchasingPrice(purchasingPrice.multiply(new BigDecimal(item.getTotalNumber()), MathContext.DECIMAL32));
                orderPurchasingPrice =  orderPurchasingPrice.add(item.getTotalPurchasingPrice(), MathContext.DECIMAL32);
            }
            BigDecimal sellingPrice = productInfo.getSellingPrice();
            if(sellingPrice == null){
                throw new ServiceException("商品单价不能不为空");
            }
            item.setTotalSellingPrice(sellingPrice.multiply(new BigDecimal(item.getTotalNumber()), MathContext.DECIMAL32));
            orderSellingPrice =  orderSellingPrice.add(item.getTotalSellingPrice(), MathContext.DECIMAL32);
            item.setProfit(profitCompute(item.getTotalSellingPrice(), item.getTotalPurchasingPrice()));
            item.setProfitRate(profitRateCompute(item.getTotalSellingPrice(), item.getTotalPurchasingPrice()));
            item.setSort(i++);
            orderProducts1.add(item);
        }
        orderInfoVo.setTotalNumber(totalNumber);
        orderInfoVo.setTotalPrice(orderPurchasingPrice);
        orderInfoVo.setTotalSell(orderSellingPrice);
        orderInfoVo.setProfit(profitCompute(orderSellingPrice, orderPurchasingPrice));
        orderInfoVo.setProfitRate(profitRateCompute(orderSellingPrice, orderPurchasingPrice));
        // 扣除对应商品对数量
        // 计算订单对总信息
        // 组装客户信息
        String clientId = orderInfoVo.getClientId();
        if(StringUtils.isNotBlank(clientId)){
            ShopCustomer customer = shopCustomerService.getById(clientId);
            if(null != customer){
                orderInfoVo.setClientName(customer.getName());
            }
        }
        productInfoService.updateBatchById(inventoryProductInfos);
        orderProductService.saveBatch(orderProducts1);
        baseMapper.updateById(orderInfoVo);
        return orderInfoVo.getId();
    }

    private BigDecimal profitCompute(BigDecimal totalSellingPrice, BigDecimal totalPurchasingPrice){
        if(null == totalSellingPrice || null == totalPurchasingPrice ){
            return null;
        }
        return totalSellingPrice.subtract(totalPurchasingPrice, MathContext.DECIMAL32);
    }

    /**
     * 计算利润率
     * @param totalSellingPrice
     * @param totalPurchasingPrice
     * @return
     */
    private BigDecimal profitRateCompute(BigDecimal totalSellingPrice, BigDecimal totalPurchasingPrice){
        if(null == totalSellingPrice || null == totalPurchasingPrice ){
            return null;
        }
//        营业利润率 = 营业利润 / 全部业务收入 × 100%
        if(totalSellingPrice.intValue() == 0){
            return new BigDecimal(0);
        }
        return profitCompute(totalSellingPrice, totalPurchasingPrice)
                .divide(totalSellingPrice, MathContext.DECIMAL32).multiply(new BigDecimal(100) ,MathContext.DECIMAL32);
    }

    /**
     * 统计分析
     * @param orderInfoVo
     * @return
     */
    @Override
    public List<OrderInfoVo> statistics(OrderInfoVo orderInfoVo) {
        if(orderInfoVo == null || !OrderInfoGroupTypeEnum.isExistType(orderInfoVo.getGroupType())){
            throw new ServiceException("参数为空或类型不存在");
        }
        return baseMapper.statistics(orderInfoVo);
    }

    /**
     * 统计分析详情
     * @param orderInfoVo
     * @return
     */
    @Override
    public OrderInfoVo statisticsInfo(OrderInfoVo orderInfoVo) {
        if(orderInfoVo == null || orderInfoVo.getStartDate() == null || orderInfoVo.getEndDate() == null){
            throw new ServiceException("参数不能为空");
        }
        List<OrderProductVo> orderInfoVos = baseMapper.statisticsCategoryList(orderInfoVo);
        OrderInfoVo infoVo = baseMapper.statisticsInfo(orderInfoVo);
        if(infoVo != null){
            infoVo.setOrderProducts(orderInfoVos);
        }
        return infoVo;
    }


    /**
     * 本月销售金额和数量
     * @param shopId
     * @return
     */
    @Override
    public OrderInfoVo currentMonthStatistics(String shopId) {
        if(StringUtils.isBlank(shopId)){
            return null;
        }
        return baseMapper.currentMonthStatistics(shopId);
    }

    public static void main(String[] args) {
        OrderInfoServiceImpl orderInfoService = new OrderInfoServiceImpl();
        BigDecimal bigDecimal = orderInfoService.profitRateCompute(new BigDecimal(0), new BigDecimal(20));
        System.err.println(bigDecimal);
    }
}
